跳到主要内容

问:文件包含 echo file_get_contents($_GET['page']);include($_GET['page']); 在面对 php伪协议时的表现。

非常好的问题!echo file_get_contents($_GET['page'])include($_GET['page']) 在 PHP 中面对伪协议(如 php://filter)时的表现是不同的。我来详细解释一下这两个函数在处理 php://filter 时的行为。


🎯 file_get_contents vs include

1. file_get_contents()php://filter

行为:

file_get_contents() 是一个用于读取文件内容的函数,它会返回文件的原始内容(字符串)。当你将 php://filter 作为文件路径传入时,它会将指定文件的内容通过 php://filter 的过滤器进行处理,然后返回处理后的内容

针对 php://filter 的表现:

当你通过 file_get_contents() 读取 php://filter 时,会:

  • 打开一个文件流
  • 应用过滤器(如 convert.base64-encodeconvert.iconv.* 等)
  • 返回过滤后的内容

举个例子:

echo file_get_contents('php://filter/read=convert.base64-encode/resource=index.php');

返回结果: 这会返回 index.phpBase64 编码内容,因为我们指定了 convert.base64-encode 过滤器。


2. include()php://filter

行为:

include() 是用于将指定文件的内容执行到当前脚本中的函数。它会将文件的内容当作 PHP 代码进行执行。如果文件中包含 PHP 代码,它会被执行,如果没有,它会被直接输出。

针对 php://filter 的表现:

当你传入 php://filter 作为路径给 include() 时:

  • PHP 会试图将 php://filter 作为一个文件进行包含。
  • 但是由于 php://filter 是伪协议,它的内容并不是实际的 PHP 脚本,因此 include() 不会执行它
  • 它返回的不是普通的 PHP 代码,而是被过滤后的数据(例如通过 convert.base64-encode 编码后的内容)。

所以 include($_GET['page']) 在遇到 php://filter 时并不会执行任何 PHP 代码,它只是将过滤后的内容作为文本包含。


🧩 区别总结:file_get_contents() vs include()php://filter 下的表现

特性file_get_contents()include()
返回类型返回文件内容,经过过滤器(如 Base64 编码等)尝试执行文件内容,若是普通文件则输出内容
PHP 代码执行不执行 PHP 代码,只返回文件内容执行 PHP 代码(如果文件是 PHP 文件)
处理 php://filter返回过滤后的内容,例如 Base64 编码不执行 PHP 代码,仅返回过滤后的文本
常用场景用于读取文件内容,尤其是用于文本内容读取用于包括并执行 PHP 文件

🔥 在渗透测试中的表现

  • file_get_contents() 可以用于读取 php://filter 中的过滤内容,比如将一个文件的内容以 Base64 编码返回。
  • include() 不会执行 php://filter 的内容,只会读取并输出经过过滤后的文本。如果你试图用 include() 去执行 PHP 代码时,它不会像普通文件那样执行。

💡 示例

假设你有以下代码(漏洞存在):

<?php
// 漏洞存在:允许通过 GET 请求包含文件
include($_GET['page']);
?>

攻击者可能构造以下请求来读取文件(但不会执行 PHP 代码):

/vuln.php?page=php://filter/read=convert.base64-encode/resource=secret.php

这将返回 secret.php 文件的 Base64 编码内容,但不会执行其中的 PHP 代码。

而如果你使用 file_get_contents

echo file_get_contents('php://filter/read=convert.base64-encode/resource=secret.php');

同样会返回该文件的 Base64 编码而不会执行其中的 PHP 代码

但如果你想执行 PHP 代码:

/vuln.php?page=secret.php

通过这种方式,你能够执行 secret.php 文件中的 PHP 代码。


🛡️ 防御建议

  • 不要让用户控制 include()require() 的路径,这可以防止文件包含漏洞。
  • 使用 filter_input()filter_var() 对用户输入进行有效验证和过滤。
  • 使用 open_basedir 限制可访问的文件路径。
  • 确保 allow_url_include 设为 Off,禁用远程文件包含。

参考链接